package utils
{
	import flash.geom.Matrix3D;
	import flash.utils.Dictionary;

	public class Game_particlesystem
	{
		// contains one source particle for each kind
		private var all_kinds:Dictionary;
		// contains many cloned particles of various kinds
		private var all_particles:Dictionary;
		// temporary variables - used often
		private var particle:Molehill_particle;
		private var particle_list:Vector.<Molehill_particle>;
		// used only for stats
		public var particles_created:uint = 0;
		public var particles_active:uint = 0;
		public var totalpolycount:uint = 0;
		
		public function Game_particlesystem()
		{
			trace("Particle system created.");
			all_kinds = new Dictionary();
			all_particles = new Dictionary();
		}
		
		// names a particular kind of particle
		public function define_particle(name:String, clone_source:Molehill_particle):void
		{
			trace("New particle type defined: " + name);
			all_kinds[name] = clone_source;
		}
		
		// updates the time step shader constants
		public function step(ms:uint):void
		{
			particles_active = 0;
			for each (particle_list in all_particles)
			{
				for each (particle in particle_list)
				{
					if (particle.active)
					{
						particles_active++;
						particle.step(ms);
					}
				}
			}
		}
		
		// renders all active particles
		public function render(view:Matrix3D,projection:Matrix3D):void
		{
			totalpolycount = 0;
			for each (particle_list in all_particles)
			{
				for each (particle in particle_list)
				{
					if (particle.active)
					{
						totalpolycount += particle.polycount;
						particle.render(view, projection);
					}
				}
			}
		}
		
		// either reuse an inactive particle or create a new one
		public function spawn(name:String, pos:Matrix3D, maxage:Number = 1000,scale1:Number = 1, scale2:Number = 50):void
		{
			var reused:Boolean = false;
			if (all_kinds[name])
			{
				if (all_particles[name])
				{
					for each (particle in all_particles[name])
					{
						if (!particle.active)
						{
							//trace("A " + name + " was reused.");
							particle.respawn(pos, maxage, scale1, scale2);
							particle.updateValuesFromTransform();
							reused = true;
							return;
						}
					}
				}
				else
				{
					trace("This is the first " + name + " particle.");
					all_particles[name] = new Vector.<Molehill_particle>;
				}
				if (!reused) // no inactive ones were found
				{
					particles_created++;
					trace("Creating a new " + name);
					trace("Total particles: " + particles_created);
					var new_particle:Molehill_particle =
						all_kinds[name].cloneparticle();
					new_particle.respawn(pos, maxage, scale1, scale2);
					new_particle.updateValuesFromTransform();
					all_particles[name].push(new_particle);
				}
			}
			else
			{
				trace("ERROR: unknown particle type: " + name);
			}
		}
		
		/**end*/
	}
}